using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Serialization;
using Nsb;
using jQueryApi;

namespace Yoshi.Fb
{
    public class FbAlbumData : FbIdentity
    {
        private const string FbDataAlbumName = "YoshiMate' App Album";

        private FbAlbum[] _albums;

        private string _dataAlbumId;
        private string _dataPhotoId;

        internal void RetrieveBlob(FnDelegate1 fn)
        {
            GetCache(FbBaseUser.id, "albums",
                     delegate(object fbo)
                         {
                             if (Script.IsValue(fbo))
                             {
                                 _albums = (FbAlbum[]) ((FbResult) fbo).data;
                                 foreach (FbAlbum n in _albums)
                                 {
                                     if (n.name == FbDataAlbumName)
                                     {
                                         _dataAlbumId = n.id;
                                         Inform.Log("Found data album, id = {0}", _dataAlbumId);
                                         GetDataPhoto(fn);
                                         return;
                                     }
                                 }
                                 CreateDataAlbum(fn);
                             }
                             else
                             {
                                 if (Script.IsValue(fn))
                                     fn(null);
                             }
                         }
                );
        }

        private void GetDataPhoto(FnDelegate1 fn)
        {
            Get(_dataAlbumId, "photos",
                delegate(object fbo)
                    {
                        FbPhoto[] photos = (FbPhoto[]) ((FbResult) fbo).data;
                        if (photos.Length > 0)
                        {
                            FbPhoto p = photos[photos.Length - 1];
                            if (Script.IsValue(p.name))
                            {
                                if (Script.IsValue(fn))
                                {
                                    //string json = (string)Script.Literal("base64_decode({0})", p.name);
                                    _dataPhotoId = p.id;
                                    string json = p.name;
                                    //json = json.Replace("\\", "\\\\");
                                    Inform.Trace("blob json = [{0}]", json);
                                    //json = "{\"user\":{\"id\":\"1305946510\",\"name\":\"Nathan Bawden\",\"first_name\":\"Nathan\",\"last_name\":\"Bawden\",\"link\":\"https://www.facebook.com/nsbawden\",\"username\":\"nsbawden\",\"birthday\":\"06/03/1962\",\"location\":{\"id\":\"112606422085862\",\"name\":\"Portland, Maine\"},\"bio\":\"I love life, it's totally awesome!\r\n\r\nA friend of mine recently asked me if I believe in the power to create an amazing life.  Well, actually, I do ... I hadn't really thought about it that way before but I like it!  It has become my theme for this phase of my life.  I am looking for other people who believe each of us has the \\\"power to create an amazing life\\\".\r\n\r\nI like to mix the spiritual things I am passionate about with everything I do in this world.  For instance, if I am hitting a nail with a hammer, I like to focus on doing it simply and perfectly with the least effort ... the Zen of hitting a nail you might call it.  I am not a fanatic about this, but I find it fun and useful to actually apply the spiritual things I discover to all the simple things in living life.\",\"gender\":\"male\",\"email\":\"nsbawden@gmail.com\",\"timezone\":-5,\"locale\":\"en_US\",\"verified\":true,\"updated_time\":\"2011-11-22T19:48:37+0000\"},\"auth\":{\"access_token\":\"AAAAADOSYSkcBANQWJzG3Xb8FGYnm9C8PD9MIlv7emcdbTuWjFOH9SvGI1w0A9vFJx2Ha8QIkuk2zUwujjUZAm1xshDfo5ZAFGylerThNpovtbvyuZAU\",\"expires\":1322243998975}}";
                                    object blob = Script.Literal("eval('(' + {0} + ')')", json);
                                    fn(blob);
                                    return;
                                }
                            }
                        }
                        if (Script.IsValue(fn))
                            fn(null);
                    }
                );
        }

        private void DeleteOldDataPhotos()
        {
            Get(_dataAlbumId, "photos",
                delegate(object fbo)
                    {
                        FbPhoto[] photos = (FbPhoto[]) ((FbResult) fbo).data;
                        foreach (FbPhoto p in photos)
                        {
                            DeleteById(p.id, null);
                        }
                    }
                );
        }

        [AlternateSignature]
        internal extern void SaveBlob(object blob);

        // ReSharper disable UnusedMember.Global
        internal void SaveBlob(object blob, FnDelegate fn)
            // ReSharper restore UnusedMember.Global
        {
            PostDataImage(blob, null);
            if (Script.IsValue(fn))
                fn();
        }

        private void CreateDataAlbum(FnDelegate1 fn)
        {
            Dictionary<string, object> values = new Dictionary<string, object>();
            values["name"] = FbDataAlbumName;

            Dictionary<string, object> privacy = new Dictionary<string, object>();
            privacy["value"] = "CUSTOM";
            privacy["FRIENDS"] = "SELF";

            values["privacy"] = Json.Stringify(privacy);

            Post(FbBaseUser.id, values, "albums",
                 delegate(object fbo)
                     {
                         _dataAlbumId = ((FbAlbum) fbo).id;
                         Inform.Log("Data album id = {0}", _dataAlbumId);
                         if (Script.IsValue(fn))
                             fn(null);
                     }
                );
        }

        private void PostDataImage(object blob, FnDelegate1 fn)
        {
            Sleep.Wait(
                delegate
                    {
                        if (Script.IsValue(_dataPhotoId))
                        {
                            UpdateDataImage(blob, fn);
                            return;
                        }
                        jQueryAjaxOptions request = new jQueryAjaxOptions();
                        FbSendStorage payload = new FbSendStorage();

                        request.Url = "php/fb/fb.photo.php";
                        request.Type = "POST";
                        request.DataType = "jsonp";

                        payload.id = Script.IsValue(_dataPhotoId) ? _dataAlbumId : _dataAlbumId;
                        payload.connection = Script.IsValue(_dataPhotoId) ? "/photos" : "/photos";
                        payload.access_token = FbBaseAuth.access_token;
                        //payload.jsonData = Encoder.Encode(Json.Stringify(blob));
                        payload.jsonData = Json.Stringify(blob);

                        request.Data = payload;

                        request.Success =
                            delegate(object data, string textStatus, jQueryXmlHttpRequest request1)
                                {
                                    Inform.Dump(data, "Posted data script result");
                                    if (Script.IsValue(fn)) fn(data);
                                    DeleteOldDataPhotos();
                                };

                        request.Error =
                            delegate { Inform.Error("Error posting data image"); };

                        jQuery.Ajax(request);
                    }, delegate { return Script.IsValue(_dataAlbumId); }
                );
        }

        private void UpdateDataImage(object blob, FnDelegate1 fn)
        {
            Dictionary<string, object> values = new Dictionary<string, object>();
            //values["name"] = Json.Stringify(blob);
            //values["method"] = "edit";
            values["message"] = Json.Stringify(blob);
            Post(_dataPhotoId, values, "comments",
                 delegate(object data)
                     {
                         Inform.Log("Data Photo Updated");
                         if (Script.IsValue(fn))
                             fn(data);
                     }
                );
        }
    }
}